package ar.edu.unrn.lia.bean;

import java.io.Serializable;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import org.primefaces.model.StreamedContent;

import ar.edu.unrn.lia.bean.datamodel.AlquilerCuotaModel;
import ar.edu.unrn.lia.bean.report.ReportUtilBean;
import ar.edu.unrn.lia.model.Alquiler;
import ar.edu.unrn.lia.model.AlquilerCuota;
import ar.edu.unrn.lia.model.AlquilerCuota.CoutaEstado;
import ar.edu.unrn.lia.model.Recibo;
import ar.edu.unrn.lia.model.ReciboItem;
import ar.edu.unrn.lia.service.AlquilerService;
import ar.edu.unrn.lia.service.ContableService;
import ar.edu.unrn.lia.service.exception.BusinessException;
import ar.edu.unrn.lia.util.FuncionesDate;

@ManagedBean(name = "cuotaPagoBean")
@ViewScoped
public class CuotaPagoBean extends GenericBean<Alquiler> implements
		Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6741809141622602428L;

	private Double tasaInteres;
	
	// AlquilerPagar
	private AlquilerCuota cuotaPagar = new AlquilerCuota();
	private AlquilerCuota[] alquilerCuotas;
	private Double montoTotal = 0D;
	private AlquilerCuotaModel alquilerCuotaModel;
	// AlquilerPagar

	private Double montoPagarPreIngreso = 0D;
	private Double maxMontoPagarPreIngreso = 0D;
	private Double minMontoPagarPreIngreso = 0D;

	private Integer montoPagar = 0;
	private Integer maxMontoPagar = 0;
	private Integer minMontoPagar = 0;

	@ManagedProperty(value = "#{alquilerService}")
	AlquilerService entityService;

	@ManagedProperty(value = "#{contableService}")
	ContableService contableService;

	@ManagedProperty(value = "#{reportUtilBean}")
	ReportUtilBean reportUtilBean;

	public ContableService getContableService() {
		return contableService;
	}

	public void setContableService(ContableService contableService) {
		this.contableService = contableService;
	}

	public ReportUtilBean getReportUtilBean() {
		return reportUtilBean;
	}

	public void setReportUtilBean(ReportUtilBean reportUtilBean) {
		this.reportUtilBean = reportUtilBean;
	}

	public Integer getMontoPagar() {
		return montoPagar;
	}

	public void setMontoPagar(Integer montoPagar) {
		this.montoPagar = montoPagar;
	}

	public AlquilerCuota getCuotaPagar() {
		return cuotaPagar;
	}

	public void setCuotaPagar(AlquilerCuota cuotaPagar) {
		this.cuotaPagar = cuotaPagar;
	}

	public AlquilerService getEntityService() {
		return entityService;
	}

	public void setEntityService(AlquilerService entityService) {
		this.entityService = entityService;
	}

	public Integer getMaxMontoPagar() {
		return maxMontoPagar;
	}

	public void setMaxMontoPagar(Integer maxMontoPagar) {
		this.maxMontoPagar = maxMontoPagar;
	}

	public Double getMontoPagarPreIngreso() {
		return montoPagarPreIngreso;
	}

	public void setMontoPagarPreIngreso(Double montoPagarPreIngreso) {
		this.montoPagarPreIngreso = montoPagarPreIngreso;
	}

	public Double getMaxMontoPagarPreIngreso() {
		return maxMontoPagarPreIngreso;
	}

	public void setMaxMontoPagarPreIngreso(Double maxMontoPagarPreIngreso) {
		this.maxMontoPagarPreIngreso = maxMontoPagarPreIngreso;
	}

	public Double getMinMontoPagarPreIngreso() {
		return minMontoPagarPreIngreso;
	}

	public void setMinMontoPagarPreIngreso(Double minMontoPagarPreIngreso) {
		this.minMontoPagarPreIngreso = minMontoPagarPreIngreso;
	}

	public Integer getMinMontoPagar() {
		return minMontoPagar;
	}

	public void setMinMontoPagar(Integer minMontoPagar) {
		this.minMontoPagar = minMontoPagar;
	}

	public AlquilerCuota[] getAlquilerCuotas() {
		return alquilerCuotas;
	}

	public void setAlquilerCuotas(AlquilerCuota[] alquilerCuotas) {
		this.alquilerCuotas = alquilerCuotas;
	}

	public Double getMontoTotal() {
		return montoTotal;
	}

	public void setMontoTotal(Double montoTotal) {
		this.montoTotal = montoTotal;
	}

	public AlquilerCuotaModel getAlquilerCuotaModel() {
		return alquilerCuotaModel;
	}

	public void setAlquilerCuotaModel(AlquilerCuotaModel alquilerCuotaModel) {
		this.alquilerCuotaModel = alquilerCuotaModel;
	}
	
	

	public Double getTasaInteres() {
		return tasaInteres;
	}

	public void setTasaInteres(Double tasaInteres) {
		this.tasaInteres = tasaInteres;
	}

	public void inicio() {
		if (!FacesContext.getCurrentInstance().isPostback()) {
			if (getId() != null) {
				try {
					setEntity(entityService.getEntityById(getId()));				
					setTasaInteres(getContableService().tasaInteresFechaHoy());	
				} catch (BusinessException e) {
					agregarMensaje(FacesMessage.SEVERITY_ERROR,"Error Tasa de Interes", e.getMessage());
					setEntity(null);
				}
				
			}
		}
	}

	public void pagarCuota() {
		try {
			// TODO getReportUtilBean().getUsuarioNombre() USER
			getContableService().pagarCuota(getEntity(), getCuotaPagar(),
					getMontoPagar(), getReportUtilBean().getUsuarioNombre());
			setEntity(entityService.getEntityById(getId()));
			agregarMensaje(FacesMessage.SEVERITY_INFO, "Pago de Cuota",
					"Operacion completada con exito.");
		} catch (BusinessException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR,
					"Error al pagar Cuota:", e.getMessage());

		} catch (Exception e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR,
					"Error al pagar Cuota:", e.getMessage());
		}
	}

	public void initValoresPreIngreso() {
		try {
			setMontoPagarPreIngreso(getEntity().montoDeudaPreIncripcion());
			setMaxMontoPagarPreIngreso(getEntity().montoDeudaPreIncripcion());
			setMinMontoPagarPreIngreso(100D);
		} catch (Exception e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR,
					"Error al pagar Cuota:", e.getMessage());
		}
	}

	public void pagar() {

	}

	public void pagarCuotaPreIngreso() {
		try {
			getContableService().pagarCuotaPreIngreso(getEntity(),
					getMontoPagarPreIngreso(),
					getReportUtilBean().getUsuarioNombre());
			setEntity(entityService.getEntityById(getId()));
			getEntity().getCuotasPreIngreso();
			Collections.sort(getEntity().getCuotasPreIngreso());
			agregarMensaje(FacesMessage.SEVERITY_INFO, "Pago Pre Ingreso:",
					"El pago se realizó con éxito.");
		} catch (BusinessException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR,
					"Error al pagar Cuota:", e.getMessage());
		} catch (Exception e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR,
					"Error al pagar Cuota:", e.getMessage());
		}
	}

	public StreamedContent imprimirPreIngreso(Recibo recibo) {
		List<ReciboItem> listPring = new ArrayList<ReciboItem>();
		listPring.addAll(recibo.getItems());
		return reportUtilBean.printReciboPreIngreso(listPring, recibo
				.getConcepto().toString());
	}

	public void seleccionCuotaPagar(AlquilerCuota alquilerCuota) {
		setCuotaPagar(alquilerCuota);
		setMaxMontoPagar(getCuotaPagar().getMontoInquilino()
				+ getEntity().montoDeudaPagoParcial());
		setMontoPagar(getMaxMontoPagar());
		setMinMontoPagar(getEntity().montoDeudaPagoParcial());
	}

	public boolean habilitarPagar(AlquilerCuota alquilerCuota) {
		if (alquilerCuota.getEstado().equals(CoutaEstado.V)
				|| alquilerCuota.getEstado().equals(CoutaEstado.PE)) {
			return true;
		} else {
			return false;
		}
	}

	public void listaAlquileresActivosParaPagarPorInmmobiliaria() {
		List<AlquilerCuota> resultado = getEntityService()
				.alquileresActivosCuotaPendientePorMes(FuncionesDate.mesHoy());
		setMontoTotal(0D);
		for (AlquilerCuota alquilerCuota : resultado) {
			setMontoTotal(getMontoTotal() + alquilerCuota.getMontoInquilino());
		}
		setAlquilerCuotaModel(new AlquilerCuotaModel(resultado));
	}

	public void onRowSelectAlquilerCuota(SelectEvent event) {
		Double resultado = 0D;
		for (AlquilerCuota acs : getAlquilerCuotas()) {
			resultado = resultado + acs.getMontoInquilino();
		}
		NumberFormat n = NumberFormat.getCurrencyInstance(Locale.US);
		agregarMensaje(FacesMessage.SEVERITY_INFO, "Monto Total Selecionado",
				n.format(resultado));
	}

	public void onRowUnSelectAlquilerCuota(UnselectEvent event) {
		onRowSelectAlquilerCuota(null);
	}

	public Double intereses(AlquilerCuota alquilerCuota) {
		Double resultado = 0D;
		try {
			resultado = getContableService().intereses(alquilerCuota);
		} catch (BusinessException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR,
					"Error Tasa de Interes", e.getMessage());
			resultado = null;
		} finally {
			return resultado;
		}
	}

	public Double totalItereses(Alquiler alquiler) throws BusinessException {
		Double resultado = 0D;
		try {
			for (AlquilerCuota cuota : alquiler.getCuotas()) {
				resultado = resultado + getContableService().intereses(cuota);
			}
		} catch (BusinessException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR,
					"Error Tasa de Interes", e.getMessage());
			resultado = null;
		} finally {
			return resultado;
		}
	}

}
